package com.stdz.counter.utils;


import com.stdz.counter.constant.MeterConstant;
import com.stdz.counter.entity.MeterModbus;
import com.sun.imageio.plugins.common.I18N;
import de.re.easymodbus.exceptions.ModbusException;
import de.re.easymodbus.modbusclient.ModbusClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.Map;

/**
 * 报警值工具类
 * @author peanut
 */
public class MeterValueUtil {


    private static final Logger LOG = LoggerFactory.getLogger(MeterValueUtil.class);

    private static final int VAL_MAX = 65536;

    public static String getValue(int val1, int val2) {
        return String.valueOf(val1 * VAL_MAX + val2);
    }

    public static String red(int al2High, int al2Low) {
        return getValue(al2High, al2Low);
    }

    public static int[] readINTEGERALARM(ModbusClient modbusClient, MeterModbus meterModbus) throws IOException, ModbusException {
        return modbusClient.ReadHoldingRegisters(MeterConstant.INT_METER_ALARM, MeterConstant.READ_METER_DIGIT);
    }

    public static int[] readBCDALARM(ModbusClient modbusClient, MeterModbus meterModbus) throws IOException, ModbusException {
        return modbusClient.ReadHoldingRegisters(MeterConstant.BCD_METER_ALARM, MeterConstant.READ_METER_DIGIT);
    }

    public static int[] readHoldingRegistersBCD(ModbusClient modbusClient, MeterModbus meterModbus) throws IOException, ModbusException {
        return modbusClient.ReadHoldingRegisters(StringUtils.isEmpty(meterModbus.getRegisterAddress()) ?  MeterConstant.BCD_REGISTER_ADDRESS
                : Integer.parseInt(meterModbus.getRegisterAddress()), MeterConstant.READ_METER_DIGIT);
    }

    public static int[] readHoldingRegistersINTEGER(ModbusClient modbusClient, MeterModbus meterModbus) throws IOException, ModbusException {
        return modbusClient.ReadHoldingRegisters(StringUtils.isEmpty(meterModbus.getRegisterAddress()) ?  MeterConstant.BCD_REGISTER_ADDRESS
                : Integer.parseInt(meterModbus.getRegisterAddress()), MeterConstant.READ_METER_DIGIT);
    }

    public static int[] readBCDSCAL(ModbusClient modbusClient, MeterModbus meterModbus) throws IOException, ModbusException {
        return modbusClient.ReadHoldingRegisters(MeterConstant.BCD_SCAL, Integer.parseInt(MeterConstant.CLEAR_MODE2));
    }


    public static int[] readINTSCAL(ModbusClient modbusClient, MeterModbus meterModbus) throws IOException, ModbusException {
        return modbusClient.ReadHoldingRegisters(MeterConstant.INT_SCAL, Integer.parseInt(MeterConstant.CLEAR_MODE2));
    }

    public static String getAlValue(int al1High, int al1Low) {

        int highAl1; int lowAl1;

        highAl1 = valueHandle(al1High, 1);

        lowAl1 = valueHandle(al1Low, 2);

        return String.valueOf(highAl1 + lowAl1);
    }

    private static int valueHandle(int value, int isParam1) {
        if (value >= 0) {
            if (isParam1 == 1) {
                LOG.debug("参数{}值为：{}", isParam1, value * VAL_MAX);
                return value * VAL_MAX;
            } else {
                LOG.debug("参数{}值为：{}", isParam1, value);
                return value;
            }
        } else {
            LOG.debug("参数{}值为：{}", isParam1, Integer.valueOf(getAlHex(value)));
            return Integer.valueOf(getAlHex(value));
        }
    }

    public  static String getAlHex(int lowOrder) {

        // 去掉符号位
        lowOrder =  Math.abs(lowOrder);

        // 转为2进制
        String al1Str = Integer.toBinaryString(lowOrder);

        String zorn = "";
        if (al1Str.length() < 16) {
            for (int i = 0; i< 16 - al1Str.length(); i++) {
                zorn += "0";
            }
        }
        al1Str = zorn + al1Str;

        /**
         * * 转为数组  遍历循环  取补码
        */
        // 转为数组
        String[] alArrStr = al1Str.split("");
        // 先转反码  再转为补码
        String str = getComplement(alArrStr);
        // 转为10进制
        int bitStr = Integer.parseInt(str, 2);
        // 返回16进制
        return String.valueOf(bitStr);
    }

    private static String getComplement (String[] alArrStr) {
        StringBuilder str = new StringBuilder();

        // 遍历  获取反码
        for (int i = 0; i < alArrStr.length; i++) {
            if (MeterConstant.BIT_ZERO_FLAG.equals(alArrStr[i])) {
                str.append(MeterConstant.BIT_ONE_FLAG);
            } else {
                str.append(MeterConstant.BIT_ZERO_FLAG);
            }
        }
        String[] code = str.toString().split("");
        Boolean isCarry = false;
        // 再去补码
        for (int i = code.length - 1; i < code.length; i--) {
            if (MeterConstant.BIT_ZERO_FLAG.equals(code[i])) {
                if (isCarry) {
                    code[i] = MeterConstant.BIT_ONE_FLAG;
                    isCarry = false;
                }
                break;
            } else {
                code[i] = MeterConstant.BIT_ZERO_FLAG;
                isCarry = true;
            }
        }
        return org.apache.commons.lang3.StringUtils.join(code);
    }


    public static int[] getScalRegisterAddress(String hex) {

        int[] registerAddress = new int[2];
        if (hex.length() > MeterConstant.READ_METER_DIGIT) {
            getFourValue(hex, registerAddress, 0, 1);
        } else {
            registerAddress[0] = 0;
            registerAddress[1] = ConversionUtil.toHexAdecimal(hex).intValue();
        }
        return registerAddress;
    }
    public static int[] getScalBCD(String hex) {

        int[] registerAddress = new int[2];
        if (hex.length() > MeterConstant.READ_METER_DIGIT) {
            String topFour = subStrTopFour(hex);
            String LaterFour = subStrTopFour(hex);
            registerAddress[0] = Integer.valueOf(topFour);
            registerAddress[1] = Integer.valueOf(LaterFour);
        } else {
            registerAddress[0] = 0;
            registerAddress[1] = Integer.parseInt(hex);
        }
        return registerAddress;
    }


    /***
     * 获取到寄存器地址(整形)
     * @param al1Hex
     * @param al2Hex
     * @return
     */
    public static int[] getRegisterAddress(String al1Hex, String al2Hex) {

        int[] registerAddress = new int[MeterConstant.READ_METER_DIGIT];
        if (al1Hex.length() > MeterConstant.READ_METER_DIGIT) {
            getFourValue(al1Hex, registerAddress, 0, 1);
        } else {
            registerAddress[0] = 0;
            registerAddress[1] = ConversionUtil.toHexAdecimal(al1Hex).intValue();
        }

        if (al2Hex.length() > MeterConstant.READ_METER_DIGIT) {
            getFourValue(al2Hex, registerAddress, 2, 3);
        } else {
            registerAddress[2] = 0;
            registerAddress[3] = ConversionUtil.toHexAdecimal(al2Hex).intValue();
        }
        return registerAddress;
    }


//    public static int[] getBCDRegisterAddress(String al1Hex, String al2Hex) {
//
//        int[] registerAddress = new int[MeterConstant.READ_METER_DIGIT];
//        if (al1Hex.length() > MeterConstant.READ_METER_DIGIT) {
//            String topFour = subStrTopFour(al1Hex);
//            String LaterFour = subStrTopFour(al1Hex);
//            registerAddress[0] = Integer.valueOf(topFour);
//            registerAddress[1] = Integer.valueOf(LaterFour);
//        } else {
//            registerAddress[0] = 0;
//            registerAddress[1] = ConversionUtil.toHexAdecimal(al1Hex);
//        }
//
//        if (al2Hex.length() > MeterConstant.READ_METER_DIGIT) {
//            String topFour = subStrTopFour(al2Hex);
//            String LaterFour = subStrTopFour(al2Hex);
//            registerAddress[2] = Integer.valueOf(topFour);
//            registerAddress[3] = Integer.valueOf(LaterFour);
//        } else {
//            registerAddress[2] = 0;
//            registerAddress[3] = ConversionUtil.toHexAdecimal(al2Hex);
//        }
//        return registerAddress;
//    }

    private static void getFourValue(String hex, int[] registerAddress, int i, int i2) {
        String topFour = subStrTopFour(hex);
        registerAddress[i] = ConversionUtil.toHexAdecimal(topFour).intValue();
        String LaterFour = subStrLaterFour(hex);
        registerAddress[i2] = ConversionUtil.toHexAdecimal(LaterFour).intValue();
    }

    private static String subStrTopFour(String data) {
        return data.substring(0, 4 - (8 - data.length()));
    }

    private static String subStrLaterFour(String data) {
        return data.substring(4 - (8 - data.length()), data.length());
    }



    private static String floatHandle(int val) {
        // 取绝对值
        val =  Math.abs(val);
        String str =  ConversionUtil.toTenAdecimal(String.valueOf(val));

        int len = str.length();

        for (int i = 0; i < MeterConstant.READ_METER_DIGIT - len; i ++) {
             str = MeterConstant.BIT_ZERO_FLAG + str;
        }
        return str;
    }


    public static Float getFloatUpperRow(int highOrder, int lowOrder){
        System.out.println(floatHandle(highOrder));
        System.out.println(floatHandle(lowOrder));
        int val = Integer.parseInt(floatHandle(highOrder) + floatHandle(lowOrder), 16);
        return Float.intBitsToFloat(val);
    }


    public static int[] readFloat(ModbusClient modbusClient, MeterModbus meterModbus) throws IOException, ModbusException {
        return modbusClient.ReadHoldingRegisters(Integer.parseInt(MeterConstant.FLOAT_REGISTER_ADDRESS,16), Integer.valueOf(MeterConstant.CLEAR_MODE2));
    }

}
